<?php

namespace app\api\controller\database;

use app\api\controller\Api;
use app\api\controller\callback\Wechat;
use app\common\log\model\ExportTask;
use app\common\system\logic\NoticeLogic;
use app\common\system\logic\UserLogic;
use app\common\third\Excel;
use app\common\third\Wechat as ThirdWechat;
use think\db\exception\DbException;
use think\facade\Db;
use think\facade\Validate;
use util\Format;
use util\Tree;

class General extends Api
{
    public function index()
    {
        $post = $this->request->post();
        $where = [];
        if (empty($post['table'])) {
            return error([], '参数错误');
        }

        $table = $post['table'];

        // 读取表的搜索配置
        $searchCfg = Db::table('tk_table_search')->where('table', $table)->find();
        if (empty($searchCfg)) {
            // 未配置搜索项
            return error([], '未配置搜索项');
        }

        if ($searchCfg) {
            $searchCfg = json_decode($searchCfg['items'], true);
            foreach ($searchCfg as $cfg) {
                $field = $cfg['Field'];
                // $post 不存在$field，则跳过
                if (!isset($post[$field])) continue;

                if (in_array($cfg['FormItemType'], ['select', 'radio', 'checkbox']) && !empty($post[$field])) {
                    $where[] = [$field, 'in', $post[$field]];
                } else {
                    // $post[$field] is 数字
                    if (is_numeric($post[$field])) {
                        if (!empty($post[$field])) $where[] = [$field, '=', $post[$field]];
                    } else {
                        if (!empty($post[$field])) $where[] = [$field, 'like', "%{$post[$field]}%"];
                    }
                }
            }
        }

        if (empty($post['sort'])) {
            $sort = 'id desc';
        } else {
            $sort = $post['sort'];
        }

        list($cfg) = Format::pagination($post);
        // 获取列表项配置
        $modelCfg = Db::table('tk_table_model')->where('table', $table)->find();
        if ($modelCfg) {
            // $model = app\common/config/model\model\ConfigStatus 转换成
            $model = '\\' . str_replace('/', '\\', $modelCfg['namespace']) . '\\' . $modelCfg['name'];
            $model = app($model);
        } else {
            return error([], '未配置模型');
        }

        $alias = [];
        $listCfg = Db::table('tk_table_list')->where('table', $table)->find();
        if ($listCfg) {
            $items = json_decode($listCfg['items'], true);
            $fields = [];
            foreach ($items as $cfg) {
                $field = $cfg['Field'];
                $fields[] = $field;
                if (!empty($cfg['Alias']) && !empty($cfg['Source'])) {
                    $alias[$field] =  [
                        'alias' => $cfg['Alias'],
                        'Source' => $cfg['Source']
                    ];
                }
            }
        } else {
            return error([], '未配置列表项');
        }

        // 获取$alias 对应的model
        foreach ($alias as $key=>$row) {
            $source = $row['Source'];
            $modelCfg = Db::table('tk_table_model')->where('table', $source)->find();
            $namespace = '\\' . str_replace('/', '\\', $modelCfg['namespace']) . '\\' . $modelCfg['name'];
            $tagModel = app($namespace);
            $alias[$key]['model'] = $tagModel;
        }

        if ($listCfg['type'] == 'list') 
        {

            $pg = $model->field($fields)->where($where)->order($sort)->paginate($cfg);
            $list = $pg->getCollection();
        
            foreach($list as $row) {
                foreach($alias as $field => $value) {
                    $relationModel = $value['model'];
                    $tag = $value['alias'];

                    $row[$tag] = $relationModel->field('id,title')->where('id', $row[$field])->find();
                }
            }

            $result['list'] = $list;
            $result['fields'] = $items;
            $result['pagination'] = Format::pgResult($pg);
        } else {
            $list = $model->where($where)->order($sort)->column('id,pid,title');
            $tree = Tree::buildTree([], $list, 0);
            $result['list'] = $tree;
        }

        return success($result);
    }

    // 读取信息
    public function read()
    {
        $post = $this->request->post();
        $table = $post['table'];
        $id = $post['id'];

        // 根据$table 获取模型
        $model = Db::table('tk_table_model')->where('table', $table)->find();
        $model = '\\' . str_replace('/', '\\', $model['namespace']) . '\\' . $model['name'];
        $model = app($model);

        try {
            $result = $model->find($id);
        } catch (DbException $e) {
            return error([], $e->getMessage());
        }

        return success($result);
    }

    public function create()
    {
        $post = $this->request->post();
        $table = $post['table'];

        // 获取表的验证规则
        $form = Db::table('tk_table_form')->where('table', $table)->find();
        $form = json_decode($form['items'], true);

        foreach ($form as $cfg) {
            $field = $cfg['Field'];

            if ($cfg['Required'] && empty($post[$field])) {
                return error([], $cfg['title'] . '不能为空');
            }

            // 根据$validate 构造正则表达式
            if (!empty($cfg['Validate']) && !preg_match($cfg['Validate'], $post[$field])) {
                return error([], $cfg['title'] . '格式错误');
            }
        }

        // 根据$table 获取模型
        $model = Db::table('tk_table_model')->where('table', $table)->find();
        $model = '\\' . str_replace('/', '\\', $model['namespace']) . '\\' . $model['name'];
        $model = app($model);

        try {
            $model->save($post);
        } catch (DbException $e) {
            return error([], $e->getMessage());
        }

        return success([], '添加成功');
    }

    public function update()
    {
        $post = $this->request->post();
        $table = $post['table'];

        // 获取表的验证规则
        $form = Db::table('tk_table_form')->where('table', $table)->find();
        $form = json_decode($form['items'], true);

        foreach ($form as $cfg) {
            $field = $cfg['Field'];

            if ($cfg['Required'] && empty($post[$field])) {
                return error([], $cfg['title'] . '不能为空');
            }

            // 根据$validate 构造正则表达式
            if (!empty($cfg['Validate']) && !preg_match($cfg['Validate'], $post[$field])) {
                return error([], $cfg['title'] . '格式错误');
            }
        }

        // 根据$table 获取模型
        $model = Db::table('tk_table_model')->where('table', $table)->find();
        $model = '\\' . str_replace('/', '\\', $model['namespace']) . '\\' . $model['name'];
        $model = app($model);

        $row = $model->find($post['id']);
        if (empty($row)) {
            return error([], '数据不存在');
        }

        try {
            $row->save($post);
        } catch (DbException $e) {
            return error([], $e->getMessage());
        }

        return success([], '更新成功');
    }

    public function delete()
    {
        $post = $this->request->post();
        $table = $post['table'];

        $model = Db::table($table);
        try {
            $model->where('id', $post['id'])->delete();
        } catch (DbException $e) {
            return error([], "删除失败");
        }
    }

    // 导出
    public function export()
    {
        $post = $this->request->post();
        $where = [];
        if (empty($post['table'])) {
            return error([], '参数错误');
        }
        $user = $this->request->user;

        $table = $post['table'];

        // 读取表的搜索配置
        $searchCfg = Db::table('tk_table_search')->where('table', $table)->find();
        if (empty($searchCfg)) {
            // 未配置搜索项
            return error([], '未配置搜索项');
        }

        if ($searchCfg) {
            $searchCfg = json_decode($searchCfg['items'], true);
            foreach ($searchCfg as $cfg) {
                $field = $cfg['Field'];
                // $post 不存在$field，则跳过
                if (!isset($post[$field])) continue;

                if (in_array($cfg['FormItemType'], ['select', 'radio', 'checkbox']) && !empty($post[$field])) {
                    $where[] = [$field, 'in', $post[$field]];
                } else {
                    // $post[$field] is 数字
                    if (is_numeric($post[$field])) {
                        if (!empty($post[$field])) $where[] = [$field, '=', $post[$field]];
                    } else {
                        if (!empty($post[$field])) $where[] = [$field, 'like', "%{$post[$field]}%"];
                    }
                }
            }
        }

        if (empty($post['sort'])) {
            $sort = 'id desc';
        } else {
            $sort = $post['sort'];
        }

        list($cfg) = Format::pagination($post);
        // 获取列表项配置
        $modelCfg = Db::table('tk_table_model')->where('table', $table)->find();
        if ($modelCfg) {
            // $model = app\common/config/model\model\ConfigStatus 转换成
            $model = '\\' . str_replace('/', '\\', $modelCfg['namespace']) . '\\' . $modelCfg['name'];
            $model = app($model);
        } else {
            return error([], '未配置模型');
        }

        $taskLogModel = new ExportTask();
        $task_start_time = time();
        $taskLogModel->save([
            'user_id' => $user['id'],
            'status' => 1,
            'task_start_time' => $task_start_time,
            'task_params' => json_encode($post)
        ]);

        $header = [];
        $listCfg = Db::table('tk_table_list')->where('table', $table)->find();
        if ($listCfg) {
            $listCfg = json_decode($listCfg['items'], true);
            $fields = [];
            foreach ($listCfg as $cfg) {
                $fields[] = $cfg['Field'];
                $header[$cfg['Field']] = $cfg['title'];
            }
        } else {
            return error([], '未配置列表项');
        }

        // 获取model
        $model = Db::table('tk_table_model')->where('table', $table)->find();   
        $model = '\\' . str_replace('/', '\\', $model['namespace']) . '\\' . $model['name'];
        $model = app($model);
        $rows = $model->field($fields)->where($where)->order($sort)->select();

        $expData = [];
        foreach ($rows as $row) {
            $data = [];
            foreach ($header as $field => $title) {
                $data[$title] = $row[$field];
            }
            $expData[] = $data;
        }

        $fileName = '【导出】' . date('YmdHis');
        $url = Excel::exportExcel($expData, $header, $fileName);
        $taskLogModel->save(['task_name' => $fileName, 'task_end_time' => time(), 'task_cost_time' => time() - $task_start_time, 'status' => 2, 'task_result' => $url]);

        // 发送微信消息
        $userLogic = new UserLogic();
        $toUser = $userLogic->getUser($user['id'], ['id', 'realname', 'work_wechat']);
        $Wechat = new ThirdWechat();
        $Wechat->send_text_message($toUser['work_wechat'], "您的导出任务已完成，点击<a href=\"{$url}\">下载</a>");

        // 创建未读通知
        $noticeLogic = new NoticeLogic();
        $noticeLogic->createNotice($user['id'], $user['id'], 1, "您的导出任务已完成，点击下载", ['url' => $url]);

        // 向websocket发送消息
        return success(['url' => $url], '导出成功');
    }
}
